package com.smartum.mpr.client.view;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.tile.TileGrid;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import com.smartum.mpr.client.services.ImageService;
import com.smartum.mpr.client.services.ImageServiceAsync;
import com.smartum.mpr.shared.Image;

import java.sql.Timestamp;
import java.util.LinkedHashMap;
import java.util.List;

/**
 */
public class GridPager extends ToolStrip {
    boolean deselect = false;

    private int pageSize = 50;
    private int pageNum;
    private final TileGrid grid;

    protected ToolStripButton firstLabel;
    protected ToolStripButton nextLabel;
    DynamicForm pageForm;
    protected TextItem pageText;
    protected ToolStripButton previousLabel;
    protected ToolStripButton lastLabel;
    protected Label totalLabel;
    protected int totalPages;

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public GridPager(TileGrid listGrid, int pageSize, ToolStripButton acceptAll, ToolStripButton declineAll, ToolStripButton submitButton) {
        GWT.log("[CONSTRUCT COMPONENT] grid pager");

        this.grid = listGrid;
        this.pageSize = pageSize;
        getNewRecords(this.grid, this.pageSize, 1);

        firstLabel = new ToolStripButton("First");
        firstLabel.setWidth(40);
        firstLabel.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                goToPage(1);
            }
        });

        previousLabel = new ToolStripButton("&lt;&lt;");
        previousLabel.setWidth(10);
        previousLabel.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                goToPage(pageNum - 1);
            }
        });

        pageText = new TextItem();
        pageText.setWidth(30);
        pageText.setShowTitle(false);
        pageText.addChangedHandler(new ChangedHandler() {
            public void onChanged(ChangedEvent event) {
                if (event.getValue() != null) {
                    int value = Integer.parseInt(event.getValue().toString());
                    goToPage(value);
                }
            }
        });

        nextLabel = new ToolStripButton("&gt;&gt;");
        nextLabel.setWidth(10);
        nextLabel.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                goToPage(pageNum + 1);
            }
        });

        lastLabel = new ToolStripButton("Last");
        lastLabel.setWidth(40);
        lastLabel.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                getTotalPages();
                goToPage(totalPages);
            }
        });

        totalLabel = new Label();
        totalLabel.setWrap(false);
        totalLabel.setWidth(50);

        setHeight(20);
        setOverflow(Overflow.VISIBLE);

        pageForm = new DynamicForm();
        pageForm.setNumCols(1);
        pageForm.setFields(pageText);
        pageForm.setWidth(30);

        addMember(acceptAll);
        addMember(declineAll);
        addMember(submitButton);
        addSeparator();

        SelectItem numberOnPage = new SelectItem();
        numberOnPage.setShowTitle(false);
        numberOnPage.setWidth(50);
        numberOnPage.addChangedHandler(new ChangedHandler() {
            public void onChanged(ChangedEvent event) {

                setPageSize(new Integer((String) event.getItem().getValue()));
                goToPage(1);
            }
        });

        LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
        valueMap.put("10", "10");
        valueMap.put("15", "25");
        valueMap.put("50", "50");
        numberOnPage.setValueMap(valueMap);
        numberOnPage.setDefaultValue("10");

        Label pageNumber = new Label("Images per page:");
        pageNumber.setWidth(85);
        addMember(pageNumber);

        addFormItem(numberOnPage);
        addSeparator();

        addMember(firstLabel);
        addMember(previousLabel);

        addMember(pageForm);
        addMember(nextLabel);
        addMember(lastLabel);
        addMember(totalLabel);
        setAlign(Alignment.RIGHT);

        goToPage(1);
    }

    public void goToPage(int pageNum) {
        GWT.log("go to page " + pageNum, null);
        getTotalPages();
        int pages = totalPages;
        if (pageNum > pages)
            pageNum = pages;
        if (pageNum < 1)
            pageNum = 1;

        getNewRecords(this.grid, pageSize, pageNum);

        if (pageNum == this.pageNum) {
            updatePagerControls(pages);
            return;
        }
        this.pageNum = pageNum;
        updatePagerControls(pages);
        if (deselect)
            grid.deselectAllRecords();


    }

    private void getTotalPages() {

        final ImageServiceAsync imageServiceAsync = GWT.create(ImageService.class);

        imageServiceAsync.getTotalUnmoderateImages(new AsyncCallback<Long>() {
            public void onFailure(Throwable caught) {
            }

            public void onSuccess(Long result) {
                int pages = (int) Math.ceil(((float) (int) result.longValue()) / ((float) pageSize));
                if (pages == 0) {
                    pages = 1;
                }
                totalPages = pages;
                updatePagerControls(pages);
            }
        });
    }

    protected void updatePagerControls(int total) {
        pageText.setValue(pageNum);
        if (pageNum == 1) {
            if (firstLabel.isVisible())
                firstLabel.hide();
            if (previousLabel.isVisible())
                previousLabel.hide();
        } else {
            if (!firstLabel.isVisible())
                firstLabel.show();
            if (!previousLabel.isVisible())
                previousLabel.show();
        }
        if (pageNum == total) {
            if (lastLabel.isVisible())

                lastLabel.hide();
            if (nextLabel.isVisible())
                nextLabel.hide();
        } else {
            if (!lastLabel.isVisible())
                lastLabel.show();
            if (!nextLabel.isVisible())
                nextLabel.show();
        }
        if (total >= 4) {
            if (!pageForm.isVisible())
                pageForm.show();
        } else {
            if (pageForm.isVisible())
                pageForm.hide();
        }

        totalLabel.setContents("(" + pageNum + "/" + total + ")");
    }

    public void getNewRecords(final TileGrid tileGrid, int pageSize, int pageNumber) {

        final MaskPanel maskPanel = new MaskPanel();
        maskPanel.show();
        pageSize = pageSize == -1 ? this.pageSize : pageSize;
        final ImageServiceAsync imageServiceAsync = GWT.create(ImageService.class);

        final RecordList recordList = tileGrid.getRecordList();

        Long timestamp = new Timestamp(0).getTime();
        if (recordList != null && pageNumber != 1) {
            final ImageRecord lastRecord = (ImageRecord) recordList.get(recordList.getLength() - 1);
            timestamp = lastRecord == null ? timestamp : lastRecord.getTimestamp();
        }
        imageServiceAsync.getImages(pageSize, timestamp, new AsyncCallback<List<Image>>() {
            public void onFailure(Throwable caught) {
                System.out.println("Error call");
                maskPanel.hide();
                maskPanel.destroy();
            }

            public void onSuccess(List<Image> result) {

                ImageRecord[] images = new ImageRecord[result.size()];
                for (int i = 0; i < result.size(); i++) {
                    final Image image = result.get(i);
                    ImageRecord imageRecord = new ImageRecord(image.getId(), image.getName(), image.getImageUrl(),
                            image.getImageUrlLittle(), image.getTimestamp());
                    images[i] = imageRecord;
                }

                tileGrid.setData(images);
                maskPanel.hide();
                maskPanel.destroy();
            }
        });
    }

    public int getPageSize() {
        return pageSize;
    }
}
